<script setup>
import { nextTick, onMounted, onUnmounted, reactive, ref, watch } from 'vue'
import { useRouter, useRoute } from 'vue-router'
import { getForumArticleDetailService, getRelativeArticleService } from '@/api/forumArticle';
import ArticleContent from './ArticleContent.vue';
import ArticleComment from './ArticleComment.vue';
import ArticleAttachment from './ArticleAttachment.vue';
import ImageViewer from '@/components/ImageViewer.vue';
import QuickPanel from './QuickPanel.vue';
import hljs from 'highlight.js' // 引入代码高亮js
import "highlight.js/styles/atom-one-light.css" // 样式
import { MdPreview, MdCatalog } from 'md-editor-v3';
import 'md-editor-v3/lib/preview.css';
import { useMdV3CatalogStore } from '@/store/mdV3Catalog';
// mdV3目录Store
const mdV3CatalogStore = useMdV3CatalogStore()

const router = useRouter()
const route = useRoute()

// 加载效果
const loadingArticleDetail = ref(false) // 文章详情加载
const loadingRecommand = ref(false) // 相似文章推荐加载

// 获取文章详情
const forumArticle = ref({})
const forumArticleAttachmentList = ref([])
const relativeForumArticleList = ref([])
const haveLike = ref()
const previewTheme = ref('default')
const codeTheme = ref('atom')
const getForumArticleDetail = async () => {
  // 开始加载
  loadingArticleDetail.value = true
  let result = await getForumArticleDetailService(
    {
      "articleId": forumArticle.value.articleId
    }
  )
  console.log("文章详情", result)
  loadingArticleDetail.value = false
  forumArticle.value = result.data.forumArticle
  forumArticleAttachmentList.value = result.data.forumArticleAttachmentList
  haveLike.value = result.data.haveLike
  previewTheme.value = result.data.previewTheme
  codeTheme.value = result.data.codeTheme

  // 为文章中的图片添加预览方法
  imagePreview()

  // 代码高亮
  // highlightCode()

  // 生成文章目录（通过DOM方式）（改为Store中获取）
  // getCatalogList()

  // 相似文章推荐
  getRelativeArticle()
}

// 相似文章推荐
const getRelativeArticle = async () => {
  // 开始加载
  loadingRecommand.value = true
  let result = await getRelativeArticleService(
    {
      "title": forumArticle.value.title,
      "articleTitle": forumArticle.value.title,
      "pageNum": 1,
      "pageSize": 5,
      "orderType": 0
    }
  )
  loadingRecommand.value = false
  console.log("相似文章推荐", result.data)
  relativeForumArticleList.value = result.data
}
// 点击推荐文章时打开新页面
const openNewWindow = (articleId) => {
  const route = router.resolve({
    path: `/article/detail/${articleId}`
  });
  window.open(route.href, '_blank');
}

// 文章中的图片预览
const previewImageList = ref([])
const imageViewerRef = ref(null)
const imagePreview = () => {
  // 等到文章加载完毕
  nextTick(() => {
    // 解析页面中的富文本，获取到图片相关dom
    // 获取文章中的所有图片img
    const imageNodeList = document.querySelector('#article-area').querySelectorAll("img")
    const imageList = []
    imageNodeList.forEach((item, index) => {
      // 获取img标签中的src属性
      const src = item.getAttribute("src")
      imageList.push(src)

      // 为每个img添加事件
      item.addEventListener("click", () => {
        // 调用子组件中的显示图片预览效果
        imageViewerRef.value.showImageViewer(index)
      })
    })

    // 获取图片组
    previewImageList.value = imageList

    console.log("图片传入给子组件", previewImageList.value)
  })
}

const scrollElement = document.documentElement;

// 生成文章目录（通过DOM方式）
const catalogList = ref([])
const getCatalogList = () => {
  nextTick(() => {
    const catalogTags = ["H1", "H2", "H3", "H4", "H5", "H6"]
    // 获取所有<h>标签
    // 先获取到所有内容
    // const contentDom = document.querySelector("#article-area")
    const contentDom = document.querySelector("#article-area-preview")
    // const contentDom = mdV3CatalogStore.getMdV3Catalog()
    console.log("所有内容", contentDom)

    // 获取所有子节点
    // const childNode = contentDom.childNodes
    const childNode = contentDom
    console.log("子节点", childNode)
    console.log("子节点个数", childNode.length)

    // 遍历所有的子节点，找<h>标签
    let index = 0
    for (let i = 0; i < childNode.length; i++) {
      console.log("挨个输出子节点", childNode[i])
    }
    childNode.forEach((item) => {
      console.log("挨个输出子节点", item)
      let tagName = item.tagName
      console.log("tagName", tagName)
      // 若未获取到节点，或节点不是<h>标签，则直接跳过
      if (tagName == undefined || !catalogTags.includes(tagName.toUpperCase())) {
        return true
      }
      console.log("tagName为：", tagName)

      // 找到节点
      index++

      // 为<h>标签添加锚点
      let id = "catalog_" + index
      item.setAttribute("id", id)

      // 解决js使用scrollIntoView()被fixed布局的header遮挡
      // item.style.scrollMarginTop = "50px";

      // 添加到目录列表中
      catalogList.value.push({
        id: id,
        title: item.innerText,
        level: Number.parseInt(tagName.substring(1)), // H1 中获取 1，并转为Number，用于目录缩进效果
        offsetTop: item.offsetTop // 每个标签距离顶部的距离
      })
    })
    console.log("目录列表为: ", catalogList)
  })
}

// key 属性动态绑定，让目录组件重新加载
const catalogComponentKey = ref(0);

// 获取文章目录2
// watch监听store中的目录
// watch(
//   () => mdV3CatalogStore.getMdV3Catalog(),
//   (newValue, oldValue) => {
//     console.log("watch监听 目录 参数：", newValue)
//     if (newValue == undefined || newValue == null) {
//       console.log("当前无目录")
//       return
//     }
//     // 生成文章目录（通过DOM方式）（改为Store中获取）
//     // getArticleCaltalog2()
//   },
//   { immediate: true, deep: true }
// )
const getArticleCaltalog2 = (param) => {
  console.log("子组件传递过来的参数：", param)
  nextTick(() => {
    const catalogTags = ["H1", "H2", "H3", "H4", "H5", "H6"]
    // 获取所有<h>标签
    // 先获取到所有内容
    // const contentDom = document.querySelector("#article-area")
    // const contentDom = document.querySelector("#article-area-preview")
    // const contentDom = mdV3CatalogStore.getMdV3Catalog()
    // console.log("所有内容", contentDom)

    // 获取所有子节点
    // const childNode = contentDom.childNodes
    const childNode = param
    console.log("子节点", childNode)
    console.log("子节点个数", childNode.length)

    // 遍历所有的子节点，找<h>标签
    let index = 0
    childNode.forEach((item) => {
      let tagName = item.tagName
      // console.log("tagName", tagName)
      // 若未获取到节点，或节点不是<h>标签，则直接跳过
      if (tagName == undefined || !catalogTags.includes(tagName.toUpperCase())) {
        return true
      }
      // console.log("tagName为：", tagName)

      // 找到节点
      index++

      // 为<h>标签添加锚点
      let id = "catalog_" + index
      item.setAttribute("id", id)
      console.log("给h标签添加锚点", item)

      // 解决js使用scrollIntoView()被fixed布局的header遮挡
      // item.style.scrollMarginTop = "50px";

      // 添加到目录列表中
      catalogList.value.push({
        id: id,
        title: item.innerText,
        level: Number.parseInt(tagName.substring(1)), // H1 中获取 1，并转为Number，用于目录缩进效果
        offsetTop: item.offsetTop // 每个标签距离顶部的距离
      })
    })
    console.log("目录列表为: ", catalogList.value)
  })
}

// 文章目录跳转
const currentAnchorId = ref(null)
const goToAnchor = (domId) => {
  const dom = document.querySelector("#" + domId)
  console.log("dom", dom)
  dom.scrollIntoView({
    behavior: "smooth",
    block: "start",
  })
  // 新增点击目录手动高亮对应目录
  // currentAnchorId.value = domId
}

// 随滚动条高亮目录效果
const listenerScroll = () => {
  // 获取当前滚动条的高度
  let currentScrollTop = document.documentElement.scrollTop
  // 高亮
  catalogList.value.some((item, index) => {
    if (
      (index < catalogList.value.length - 1 && currentScrollTop >= catalogList.value[index].offsetTop
        && currentScrollTop < catalogList.value[index + 1].offsetTop)
      || (index == catalogList.value.length - 1 && currentScrollTop > catalogList.value[index].offsetTop)
    ) {
      console.log("当前高亮item", item)
      console.log("当前高亮index", index)
      currentAnchorId.value = item.id
      return true
    }
  })
}

onMounted(() => {
  window.addEventListener("scroll", listenerScroll, false)
})

onUnmounted(() => {
  window.removeEventListener("scroll", listenerScroll, false)
})

// 借助 highlight.js 高亮代码块
// const highlightCode = () => {
//   // 等到文章加载完毕
//   nextTick(() => {
//     let bolcks = document.querySelectorAll("pre code")
//     bolcks.forEach((item) => {
//       hljs.highlightBlock(item)
//     })
//   })
// }

// 父级：修改点赞数和点赞状态
const parentDoArticleLike = () => {
  // 更新点赞数
  let goodCount = 1
  if (haveLike.value == true) {
    // 若已经点过赞，则-1
    goodCount = -1
  }
  forumArticle.value.likeCount = forumArticle.value.likeCount + goodCount

  // 修改点赞状态
  haveLike.value = !haveLike.value
}

// 父级：修改文章评论数
const parentChangeCommentCount = () => {
  forumArticle.value.commentCount = forumArticle.value.commentCount + 1
}

// watch监听路由参数
watch(
  () => route.params,
  (newValue, oldValue) => {
    console.log("路由参数：", newValue)
    if (newValue == undefined) {
      console.log("当前无路由")
      return
    }
    forumArticle.value.articleId = newValue.articleId
    // 根据路由参数获取文章详情
    getForumArticleDetail()
  },
  { immediate: true, deep: true }
)

</script>

<template>
  <div class="article-detail">
    <div class="wrapper">
      <!-- 文章相关 -->
      <div class="article-relate">
        <!-- 文章内容 -->
        <ArticleContent v-loading="loadingArticleDetail" :forumArticle="forumArticle" :previewTheme="previewTheme"
          :codeTheme="codeTheme" @parentGetArticleCatalog="getArticleCaltalog2">
        </ArticleContent>
        <!-- 文章附件 -->
        <ArticleAttachment v-if="forumArticleAttachmentList" :forumArticleAttachmentList="forumArticleAttachmentList">
        </ArticleAttachment>
        <!-- 文章评论 -->
        <ArticleComment :forumArticle="forumArticle" @parentChangeCommentCount=parentChangeCommentCount>
        </ArticleComment>

        <!-- 左侧快捷操作：点赞、评论、下载附件 -->
        <QuickPanel @parentDoArticleLike="parentDoArticleLike" :forumArticleId="Number(forumArticle.articleId)"
          :likeCount="forumArticle.likeCount" :haveLike="haveLike" :commentCount="forumArticle.commentCount">
        </QuickPanel>
      </div>
      <!-- 文章侧边栏 -->
      <div class="article-detail-sidebar">
        <!-- 文章目录 -->
        <div class="catalog-detail">
          <div class="info">
            <div class="catalog-box">
              <div class="catalog-title">目录</div>
              <div class="catalog-list">
                <div v-if="catalogList.length == 0" class="no-catalog">未解析到目录</div>
                <div v-else v-for="item in catalogList">
                  <div :class="['catalog-item', item.id == currentAnchorId ? 'active' : '']"
                    :style="{ 'padding-left': item.level * 15 + 'px' }" @click="goToAnchor(item.id)">
                    {{ item.title }}
                  </div>
                </div>
              </div>
            </div>

            <!-- 类似文章推荐 -->
            <div class="relate-command">
              <div class="command-title">相似推荐</div>
              <div class="command-list" v-loading="loadingRecommand">
                <ul>
                  <li v-for="item in relativeForumArticleList" @click="openNewWindow(item.articleId)">
                    <div class="command-article-title" v-html="item.title"></div>
                  </li>
                </ul>
              </div>
            </div>
          </div>
        </div>
        <!-- 文章目录2 -->
        <!-- <div class="article-catalog2">
          <div class="article-catalog2-body">
            文章目录2
          </div>
        </div> -->
        <!-- 其他 -->
        <!-- <div class="article-commend">
          <div class="article-commend-body">
            文章推荐
          </div>
        </div> -->
      </div>
    </div>
    <!-- 图片预览效果 -->
    <!-- <ImageViewer ref="imageViewerRef" :previewImageList="previewImageList"></ImageViewer> -->
  </div>
</template>

<style scoped>
.article-detail {
  background-color: #f2f3f5;
  height: 100%;
}

.article-detail .wrapper {
  width: 1200px;
  margin: 0 auto;
  display: flex;
  justify-content: space-between;
  padding: 20px 0 0;
}

/* 文章相关 */
.article-detail .wrapper .article-relate {
  width: 870px;
  margin-bottom: 100px;
  border-radius: 5px;

  /* 父级开启相对定位 */
  position: relative;
}

/* 文章侧边栏 */
.article-detail-sidebar {
  width: 300px;
  /* background-color: wheat; */
  position: relative;
}

.article-detail-sidebar .catalog-detail {
  width: 100%;
  height: 200px;
  position: absolute;
  top: 0px;
  right: 0px;
}

.article-detail-sidebar .catalog-detail .info {
  width: 300px;
  position: fixed;
  border-radius: 4px;
  /* background-color: #fff; */
}

.article-detail-sidebar .catalog-detail .info .catalog-box {
  background-color: #fff;
  margin-bottom: 20px;
  border-radius: 4px;
}

.article-detail-sidebar .catalog-detail .info .catalog-title {
  padding: 10px;
  border-bottom: 1px solid #ddd;
}

.article-detail-sidebar .catalog-detail .info .catalog-list {
  /* max-height: calc(100vh - 200px); */
  min-height: 40px;
  max-height: 245px;
  overflow: auto;
  padding: 5px;
}

.article-detail-sidebar .catalog-detail .info .catalog-list .no-catalog {
  text-align: center;
  color: #5f5d5d;
  line-height: 40px;
  font-size: 13px;
}

.article-detail-sidebar .catalog-detail .info .catalog-list .catalog-item {
  cursor: pointer;
  line-height: 35px;
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
  color: #555666;
  border-radius: 3px;
  font-size: 14px;
  /* 添加白色边框，占位用，避免鼠标移入导致抖动 */
  border-left: 4px solid #fff;
  /* js使用scrollIntoView()被遮挡 */
  /* scroll-margin-top: 100px; */
}

.article-detail-sidebar .catalog-detail .info .catalog-list .catalog-item:hover {
  /* background-color: #eeeded; */
  color: #3da00b;
}

.article-detail-sidebar .catalog-detail .info .catalog-list .active {
  border-left: 4px solid green;
  border-radius: 0px 3px 3px 0px;
  /* background-color: #eeeded; */
  color: #3da00b;
}

/* .article-detail-sidebar .catalog-detail .info .catalog-list .active::before {
  left: 0;
  top: 0;
  width: 20px;
  height: 20px;
  background-color: pink;
} */

/* 类似文章推荐 */
.article-detail-sidebar .catalog-detail .info .relate-command {
  background-color: #fff;
  border-radius: 4px;
}

.article-detail-sidebar .catalog-detail .info .relate-command .command-title {
  padding: 10px;
  border-bottom: 1px solid #ddd;

}

.article-detail-sidebar .catalog-detail .info .relate-command .command-list {
  padding-bottom: 10px;
}

.article-detail-sidebar .catalog-detail .info .relate-command .command-list ul li {
  padding: 12px 20px;
  cursor: pointer;
}

.article-detail-sidebar .catalog-detail .info .relate-command .command-list ul li:hover {
  background-color: #f7f8fa;
}

.article-detail-sidebar .catalog-detail .info .relate-command .command-list ul li .command-article-title {
  font-size: 14px;
  font-weight: 400;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* 文章目录2 */
.article-detail-sidebar .article-catalog2 {
  width: 300px;
  /* height: 600px; */
  position: absolute;
  top: 200px;
  /* background-color: white; */
}

.article-detail-sidebar .article-catalog2 .article-catalog2-body {
  width: 300px;
  height: 200px;
  position: fixed;
  background-color: red;
}

/* 文章推荐 */
.article-detail-sidebar .article-commend {
  width: 300px;
  height: 200px;
  position: absolute;
  top: 500px;
}

.article-detail-sidebar .article-commend .article-commend-body {
  width: 300px;
  height: 100px;
  position: fixed;
  background-color: blue;
}
</style>